跳到主要内容

JS 的精度之谜

什么是精度问题

为什么会有精度问题

先提供一个标准回答,因为 ECMAScript 规范要求 JavaScript 运行时按照 IEEE 754 的 64 位存储法,存储 Number 类型。这在浮点数和大数情况下不安全。 根本原因,用有限的数表示无限的数是不可能的。 $$V= (-1)^S\cdot M \cdot 2^E$$ 其中,

  • $(-1)^S$ 表示符号位
  • $M \in [1,2)$ 表示底数
  • 2 表示基数
  • $E$ 表示指数

通常,以 10 为基数的科学计数法(scientific notation)比较常见,但是,计算机中,为了通过「补码」实现更高效地运算,通常采用以 2 为基数的科学计数法。

3264
S11
M811
E2352

问题就出在 M 上,在 1 到 2 中间有无数个小数,无论我们采取多少位,都不能穷尽所有的小数,这就意味着,用上述的方法,总有无法被准确表示的数。

这里有个问题,如何以 0.2 为例,解释一下计算过程

  • 0.1 是正数,所以 S = 0
  • 接下来,要用科学计数法,表示 0.1

如何避免精度问题

  • 避免直接使用浮点数、大数进行运算

用有限的数表示无限的数是不可能的